package cn.com.cdb.ldms.helper;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.util.FileUtil;

import java.io.File;
import java.util.*;

@Slf4j
public class MybatisPlusGeneratorHelper {
    private MybatisPlusGeneratorHelper() {
    }

    public static void beforeGenerator(Param param) {
        //拷贝模版
        try {
            String templatesSourceDir = System.getProperty("user.dir") + param.templatePath;
            String templatesTargetDir = System.getProperty("user.dir") + param.getBaseSubModuleName() + "/src/test/resources/templates/";
            FileUtil.copyDir(new File(templatesSourceDir), new File(templatesTargetDir));
        } catch (Exception ex) {
            log.error("文件拷贝错误", ex);
        }
    }

    public static void generatorCode(Param param) {
        final String projectPath = System.getProperty("user.dir") + param.getBaseSubModuleName();
        beforeGenerator(param);
        FastAutoGenerator.create(param.getDbUrl()
                        , param.getDbUsername(), param.getDbPassword())
                .globalConfig((scanner, builder) ->
                        builder.author(System.getProperty("user.name"))
                                .commentDate("yyyy-MM-dd")
                                // System.getProperty("user.dir") 表示整个项目的根目录
                                .enableSpringdoc()
                                .disableOpenDir()       // 禁止打开输出目录 默认值:true
                                .outputDir(System.getProperty("user.dir") + param.getBaseSubModuleName() + "/src/main/java"))
                .packageConfig((scanner, builder) -> {
                            final String pathMapperXml = "src/main/resources/mapper";
                            builder
                                    .parent(param.getBaseSubModulePackage())
                                    .mapper("mapper")           //Mapper 包名 默认值:mapper
                                    .pathInfo(Collections.singletonMap(OutputFile.xml, projectPath + pathMapperXml));
                        }// 设置mapperXml生成路径
                )
                .injectionConfig(builder -> {
                    final String pathJava = "src/main/java";

                    final String dtoPackage = param.getBaseSubModulePackage() + ".dto";
                    Map<String, Object> customMap = new HashMap<>();
                    customMap.put("dtoPackageIn", dtoPackage + ".in");
                    customMap.put("dtoPackageOut", dtoPackage + ".out");
                    customMap.put("baseSubModulePackage", param.getBaseSubModulePackage());
                    customMap.put("basePackage", param.getBasePackage());
                    customMap.put("seqName", param.seqName);
                    builder.customMap(customMap);
                    // 定义入参
                    builder.customFile(builder2 -> builder2.fileName("In.java").templatePath("templates/dtoIn.java.ftl") // 模板路径
                            .filePath(projectPath + pathJava) // 输出根目录
                            .packageName(dtoPackage + ".in") // 实际包路径
                            .enableFileOverride());
                    // 定义出参
                    builder.customFile(builder2 -> builder2.fileName("Out.java").templatePath("templates/dtoOut.java.ftl") // 模板路径
                            .filePath(projectPath + pathJava) // 输出根目录
                            .packageName(dtoPackage + ".out") // 实际包路径
                            .enableFileOverride());
                })
                .strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名，多个英文逗号分隔，所有输入 all")))
                        .addTablePrefix(scanner.apply("请输入要过滤的表前缀，多个英文逗号分隔")) // 设置过滤表前缀
                        .entityBuilder()
                        .idType(IdType.INPUT)
                        .enableLombok()
                        .enableTableFieldAnnotation()
                        .addTableFills(new Column("create_time", FieldFill.INSERT))
                        .serviceBuilder()
                        .controllerBuilder()
                        .enableRestStyle() // 开启RestController注解
                        .mapperBuilder()// mapper策略配置
//                        .superClass("com.github.yulichang.base.MPJBaseMapper")
                        .formatMapperFileName("%sMapper")
                        .mapperAnnotation(org.apache.ibatis.annotations.Mapper.class) // 替换过时的enableMapperAnnotation()
                        .formatXmlFileName("%sMapper").enableBaseColumnList())
                .templateEngine(new FreemarkerTemplateEngine()).execute();
    }

    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }

    @Data
    @Builder
    public static class Param {
        /**
         * 子工程名称
         */
        private String baseSubModuleName;
        /**
         * 子工程报名
         */
        private String baseSubModulePackage;
        /**
         * 工程代码基础包package定义
         */
        private String basePackage;
        private String templatePath;
        private String dbUrl;
        private String dbUsername;
        private String dbPassword;
        private String seqName;
    }

}
